package org.hzandyy.framework.liteflow.controller;

import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.enums.CmpStepTypeEnum;
import com.yomahub.liteflow.flow.LiteflowResponse;
import com.yomahub.liteflow.flow.entity.CmpStep;
import com.yomahub.liteflow.script.ScriptExecutorFactory;
import com.yomahub.liteflow.slot.DefaultContext;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.hzandyy.framework.liteflow.context.CustomContext;
import org.hzandyy.framework.liteflow.context.ReqData;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author Hu Zhi
 * @since 2023/12/1 9:41
 */
@RestController
@Slf4j
public class FlowController {

    @Resource
    private FlowExecutor flowExecutor;

    @GetMapping("/flow")
    public void flow(@RequestParam String chain) {
        LiteflowResponse response = flowExecutor.execute2Resp(chain, "");
    }

    @GetMapping("/context")
    public void context() {
        /**
         * 1 param 是入参 通过 'this.getRequestData()' 方法获取
         * 2 上下文可通过class传入
         * 3 上下文可通过实现类传入
         * 4 class和实现类不可同时传入
         */
        flowExecutor.execute2Resp("chain_context", new ReqData(), CustomContext.class, DefaultContext.class);
    }

    @GetMapping("/resp")
    public void resp() {
        LiteflowResponse response = flowExecutor.execute2Resp("chain_resp", null, CustomContext.class);

        // 执行结果
        log.info("执行是否执行成功? {}", response.isSuccess() ? "是" : "否");

        // 如果执行失败 获取失败信息
        if (!response.isSuccess()) {
            Exception exception = response.getCause();
            log.info("执行中抛出的异常是: '{}', 异常信息: '{}'", exception.getClass(), exception.getMessage());
        }

        // 获取执行步骤
        Map<String, List<CmpStep>> stepMap = response.getExecuteSteps();
        for (Map.Entry<String, List<CmpStep>> entry : stepMap.entrySet()) {
            String key = entry.getKey();
            List<CmpStep> steps = entry.getValue();
            for (CmpStep step : steps) {
                String nodeId = step.getNodeId();
                String nodeName = step.getNodeName();
                CmpStepTypeEnum stepType = step.getStepType();
                log.info("key: '{}', nodeId: '{}', nodeName: '{}', stepType: '{}'", key, nodeId, nodeName, stepType);
            }
        }
//        Queue<CmpStep> stepQueue = response.getExecuteStepQueue();

        // 获取执行完的数据上下文
        CustomContext context = response.getContextBean(CustomContext.class);
        log.info("content: '{}'", context.toString());

        // 执行顺序
        log.info("chain: {}", response.getExecuteStepStrWithTime());
    }

    @GetMapping("/script")
    public void script(@RequestParam(required = false) boolean refresh) throws Exception {
        if (refresh) {
            InputStream inputStream = FlowController.class.getClassLoader().getResourceAsStream("xml-script-file/ScriptS1.java");
            try (inputStream) {
                if (Objects.nonNull(inputStream)) {
                    List<String> lines = IOUtils.readLines(inputStream, StandardCharsets.UTF_8);
                    StringBuilder script = new StringBuilder();
                    System.out.println("-------------------- script --------------------");
                    lines.forEach(line -> {
                        System.out.println(line);
                        script.append(line);
                    });
                    System.out.println("-------------------- script --------------------");
                    ScriptExecutorFactory.loadInstance().getScriptExecutor("java").load("s1", script.toString());
                }
            }
        }
        flowExecutor.execute2Resp("chain_script", "");
    }

}
